#include <iostream>
#include <fcntl.h>
#include <unistd.h>


void set_no_block(int fd)
{
    int fl = fcntl(fd, F_GETFL);
    if(fl < 0)
    {
        std::cout << "fcntl fail!!" << std::endl;
        exit(errno);
    }
    fcntl(fd, F_SETFL, fl | O_NONBLOCK);//文件描述符的属性 -- 位图
}


//非阻塞轮询
int main()
{
    set_no_block(0);//将cin设为非阻塞读

    char buffer[1024];
    while(true)
    {
        int sz = read(0, buffer, sizeof(buffer));
        if(sz > 0)
        {
            buffer[sz - 1] = '\0'; //把输入的回车也去掉, read这种系统接口会记录你输入的每一个字符, 包括回车; 而向cin这种库函数, 会自动帮你把回车去掉 
            std::cout << buffer << ", sz: " << sz << std::endl; 
            sleep(1);
        }
        else if(sz < 0)//在非阻塞读这里 有两种情况: 1.read出错了;  2.底层缓冲区的数据没准备好;   ---  所以要根据[errno]判断
        {
            if(errno == EAGAIN || errno == EWOULDBLOCK/*两个写一个就行*/) //数据没准备好
            {
                std::cout << "数据没准备好, sz: " << sz << std::endl;
                
                //做你自己要做的事情(利用等待时间做别的事情)
                sleep(1);//用休眠代替一下

                continue;
            }
            else if(errno == EINTR) //进程被信号打断暂停了, read实际上没出错
            {
                continue;//继续从底层缓冲区里读
            }
            else //read真出错了
            {
                std::cout << "read fail!!!!!" << std::endl;
                exit(errno);
            }

        }
        else //read返回值为0 -- 表示读到文件结尾eof了, (ps: linux下, 输入ctrl+d也是标识文件输入结束, read返回0, 代表读到eof)
        {
            std::cout << "非阻塞轮询即将退出, sz: " << sz << std::endl;
            break;//退出轮询
        }
    }



    return 0;
}